<?php
declare (strict_types=1);

namespace sws;

use app\event\SwsEvent;
use sws\event\FrameEvent;
use sws\route\Route;

class App
{
    /**
     * sws框架版本
     */
    protected $version = '1.0.0';

    /**
     * 调试模式
     * @var bool
     */
    protected $debug = false;

    /**
     * @var
     */
    protected $servers;

    /**
     * 初始化config和注册异常
     */
    public function __construct()
    {
        Config::getInstance()->initialize();
        Error::getInstance()->registerErrorHandle();
    }

    /**
     * 获取实例
     * @return App
     */
    public static function getInstance(): App
    {
        return Container::getInstance()->make(App::class);
    }

    /**
     * 框架初始化
     */
    public function initialize()
    {
        //初始化设置
        $appConfig = Config::getInstance()->get('app');
        $this->debug = $appConfig['debug'] ?? false;
        foreach ($appConfig['php-ini'] ?? [] as $key => $value) {
            ini_set($key, $value);
        }
        //初始化路由解析
        include_once BASE_PATH . 'route/route.php';
        Container::getInstance()->make(Route::class)->parserRoute();
        //监听框架事件
        FrameEvent::getInstance()->listenEvent();

        //初始化Log

        //执行初始化后事件
        Event::getInstance()->trigger([SwsEvent::class, 'initialize']);
    }

    /**
     * 运行服务
     */
    public function run()
    {
        //解析参数命令
        list($serverName, $option, $daemonize) = Console::getInstance()->getCommand();

        //设置server配置项为守护进程
        if ($daemonize) {
            Config::getInstance()->set("server.servers.$serverName.setting.daemonize", true);
        }

        $serverConfig = Config::getInstance()->get("server.servers.$serverName");
        $server = new Server($serverName, $serverConfig);
        Container::getInstance()->bind('server', $server);
        //如果要启动服务，做初始化
        if ($option == 'start' || $option == 'restart') {
            $this->initialize();
        }
        $server->$option();
    }

    /**
     * 获取框架版本号
     * @return string
     */
    public function getVersion(): string
    {
        return $this->version;
    }


}